package com.zhang.controller;


import cn.hutool.core.map.MapUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.zhang.common.DTO.PasswordDto;
import com.zhang.common.DTO.RegisterDto;
import com.zhang.common.lang.Const;
import com.zhang.common.lang.Result;
import com.zhang.entity.Blog;
import com.zhang.entity.Comment;
import com.zhang.entity.User;
import com.zhang.mapper.BlogMapper;
import com.zhang.service.BlogService;
import com.zhang.service.CommentService;
import com.zhang.service.UserService;
import com.zhang.utils.ShiroUtil;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author 张立松
 * @since 2023-03-31
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;
    @Autowired
    BlogService blogService;
    @Autowired
    CommentService commentService;
    @Autowired
    BlogMapper blogMapper;

    @GetMapping("/a")
    public String a(){
        return "hello";
    }

    @GetMapping("/get")
    public Result get(@RequestParam("id")Long id){
        User user = userService.getById(id);
        return Result.success(MapUtil.builder().put("id",user.getId())
                .put("username",user.getUsername())
                .put("nickname",user.getNickname())
                .put("avatar",user.getAvatar()).map());
    }

    //注册账号
    @PostMapping("/register")
    public Result registerUser(@RequestBody @Validated RegisterDto registerDto){
        List<User> userList = userService.list(new QueryWrapper<>(null));
        for(User user : userList){
            if(user.getUsername().equals(registerDto.getUsername())){
                return Result.fail("该用户名已被注册");
            }
        }
        userService.addUser(registerDto);
        return Result.success("操作成功");
    }

    //注销用户
    @RequiresAuthentication     //登陆之后才能访问
    @PostMapping("/delete")
    public Result deleteUserById(@RequestParam("userId")Long userId,@RequestParam("password")String password){
        if(ShiroUtil.getProfile().getId().longValue()!=userId.longValue()){
            return Result.fail("登录信息不匹配，无法注销");
        }
        User user = userService.getById(userId);
        if(!SecureUtil.md5(password).equals(user.getPassword())){
            return Result.fail("密码不正确，无法注销");
        }
        //删除用户
        userService.removeById(userId);
        //删除用户的博客及对应博客的所有评论
        List<Blog> blogs = blogService.list(new QueryWrapper<Blog>().eq("user_id", userId));
        for(Blog blog : blogs){
            commentService.remove(new UpdateWrapper<Comment>().eq("blog_id",blog.getId()));
        }
        blogService.remove(new UpdateWrapper<Blog>().eq("user_id",userId));
        //删除用户的所有评论并将评论所在的博客评论数减1
        List<Comment> comments = commentService.list(new QueryWrapper<Comment>().eq("user_id", userId));
        for(Comment comment : comments){    //先将对应博客的评论数减1
            Long blogId = comment.getBlogId();
            blogMapper.updateCommentSelfSubtract(blogId);
        }
        commentService.remove(new UpdateWrapper<Comment>().eq("user_id",userId));
        //删除保存在服务器端的用户头像
        deleteUserAvatar(user.getUsername());
        return Result.success("您已成功注销账号");
    }

    //修改用户名
    @RequiresAuthentication     //登陆之后才能访问
    @PostMapping("/updateUsername")
    public Result updateUsername(@RequestParam("username") String username){
        if(username.length()>15){
            return Result.fail("最长15个字符");
        }
        if(username.length()==0){
            return Result.fail("用户名不能为空");
        }
        User user = userService.getById(ShiroUtil.getProfile().getId());
        if(user.getUsername().equals(username)){
            return Result.success("修改成功");
        }
        List<User> userList = userService.list(new QueryWrapper<>(null));
        for(User u : userList){
            if(u.getUsername().equals(username)){
                return Result.fail("该用户名已被注册");
            }
        }
        user.setUsername(username);
        updateAvatarName(user);
        userService.updateById(user);
        return Result.success("修改成功");
    }

    //修改昵称
    @RequiresAuthentication
    @PostMapping("/updateNickname")
    public Result updateNickname(@RequestParam("nickname") String nickname){
        if(nickname.length()>8){
            return Result.fail("最长8个字符");
        }
        if(nickname.length()==0){
            return Result.fail("昵称不能为空");
        }
        User user = userService.getById(ShiroUtil.getProfile().getId());
        if(!user.getNickname().equals(nickname)){
            user.setNickname(nickname);
            userService.updateById(user);
            //修改其他两个数据库中的相应昵称
            blogService.updateUserInfo(user.getId(),"user_nickname",nickname);
            commentService.updateUserInfo(user.getId(),"user_nickname",nickname);
        }
        return Result.success("修改成功");
    }

    //修改密码
    @RequiresAuthentication
    @PostMapping("/updatePassword")
    public Result updatePassword(@RequestBody PasswordDto passwordDto){
        if(!passwordDto.getNewPassword().equals(passwordDto.getCheckPassword())){
            return Result.fail("两次输入密码不一致");
        }
        User user = userService.getById(ShiroUtil.getProfile().getId());
        if(!user.getPassword().equals(SecureUtil.md5(passwordDto.getOldPassword()))){
            return Result.fail("密码不正确");
        }
        user.setPassword(SecureUtil.md5(passwordDto.getNewPassword()));
        userService.updateById(user);
        return Result.success("修改成功");
    }

    //更新用户头像
    @RequiresAuthentication
    @PostMapping("/avatar")
    public Result updateAvatar(@RequestParam("file") MultipartFile multipartFile) throws IOException {
        String fileName = multipartFile.getOriginalFilename();
        String[] splits = fileName.split("\\.");  //用于获取文件后缀
        String avatarName = ShiroUtil.getProfile().getUsername()+"."+splits[splits.length-1];
        String avatarPath = Const.Default_Avatar_FilePath+"/"+avatarName;

        File file = new File(Const.Default_Avatar_FilePath);
        if(!file.exists()){     //目录不存在则创建目录
            file.mkdirs();
        }

        //先删除以前的头像
        deleteUserAvatar(ShiroUtil.getProfile().getUsername());
        //头像存储到对应路径
        File upFile = new File(avatarPath);
        multipartFile.transferTo(upFile);   //保存新头像

        //更新数据库中的头像路径
        User user = userService.getById(ShiroUtil.getProfile().getId());
        user.setAvatar(Const.Base_Url+"/user/getAvatar/"+avatarName);
        userService.updateById(user);
        //修改其他两个数据库中的相应头像路径
        blogService.updateUserInfo(user.getId(),"user_avatar",user.getAvatar());
        commentService.updateUserInfo(user.getId(),"user_avatar",user.getAvatar());

        return Result.success("");
    }

    //获取头像文件
    @GetMapping("/getAvatar/{path}")
    public void getAvatar(@PathVariable("path") String path , HttpServletResponse response) throws IOException {
        File file = new File(Const.Default_Avatar_FilePath+"/"+path);
        FileInputStream fileInputStream = new FileInputStream(file);
        ServletOutputStream servletOutputStream = response.getOutputStream();
        byte[] bytes = new byte[1024];
        while (fileInputStream.read(bytes)!=-1){
            servletOutputStream.write(bytes);
            servletOutputStream.flush();
        }
        fileInputStream.close();
        servletOutputStream.close();
        return;
    }

    //删除本地的用户头像
    private Boolean deleteUserAvatar(String username){
        File file1 = new File(Const.Default_Avatar_FilePath+"/"+username+".jpg");
        File file2 = new File(Const.Default_Avatar_FilePath+"/"+username+".jpeg");
        File file3 = new File(Const.Default_Avatar_FilePath+"/"+username+".png");
        if(file1.exists()){
            file1.delete();
        }
        if(file2.exists()){
            file2.delete();
        }
        if(file3.exists()){
            file3.delete();
        }
        return true;
    }
    //头像更名
    private Boolean updateAvatarName(User user){
        String[] split = user.getAvatar().split("/");
        String avatarName = split[split.length-1];
        File avatarFile = new File(Const.Default_Avatar_FilePath+"/"+avatarName);
        String newAvatarName = user.getUsername()+"."+avatarName.split("\\.")[1];
        File newAvatarFile = new File(Const.Default_Avatar_FilePath+"/"+newAvatarName);
        if(avatarFile.exists()){
            avatarFile.renameTo(newAvatarFile);     //重命名
        }
        user.setAvatar(Const.Base_Url+"/user/getAvatar/"+newAvatarName);
        return true;
    }
}

